package thread;

/**
 * 线程并发安全问题
 */
public class SyncDemo1 {
    static boolean flag = false;
    static boolean flag1= false;
    public static void main(String[] args) {
        Bank bank = new Bank();
        // 记录多少次卡bug成功
        int sum =0;
        // 模拟多线程

        while(true){
            sum ++;
            Thread t1 = new Thread(() -> flag = bank.getMoney(20000));
            Thread t2 = new Thread(() -> flag1 = bank.getMoney(20000));

            try{
                // 主线程
                Thread.sleep(5);
            }catch (Exception e){
                e.printStackTrace();
            }


            t1.start();
            t2.start();


            // 判断
            if(flag && flag1){
                System.out.println("卡bug成功，循环次数为：" + sum);
                break;
            }else{
               flag = false;
               flag1 = false;
               bank.saveAccount(20000);
            }
        }



    }
}

class Bank{
    private int account = 20000;

    /*
    synchronized 修饰的方法，保证线程安全
     */
    public synchronized boolean getMoney(int money){
        int account = getAccount();
        if(account >= money){
            account = account - money;
            Thread.yield();  // 主动放弃时间片
            // 分析出现bug的原因是：
            // 系统给一个线程分的时间片用完了，但是线程并没有执行完，
            // 此时线程被挂起，其他线程可以执行，由于线程1没有更新账户余额，
            // 线程2去找到的余额还是原来的没有更新的余额，
            saveAccount(account);
            return true;
        }
        return false;
    }

    // 查询余额
    public int getAccount(){
        return account;
    }

    // 更新存钱或取钱操作后的余额
    public void saveAccount(int account){
        this.account = account;
    }
}
